<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * MY_Loader
 *
 * @author Simon Emms <simon@simonemms.com>
 */
class MY_Loader extends CI_Loader {






    var $_my_varmap = array(
        'user_agent' => 'user_agent', /* Override the parent class and call it 'user_agent' */
    );
    var $_ci_forms = array();
    var $_ci_form_paths	= array();
    
    var $_ui_types = array(
        'css', 'js', 'ui',
    );







    /**
     * Construct
     *
     * Extends construct to allow form
     * paths
     */
    public function __construct() {
        parent::__construct();
        
        /* Merge the varmaps */
        $this->_ci_varmap = array_merge($this->_ci_varmap, $this->_my_varmap);

        /* Add the form paths */
        $this->_ci_form_paths = array(APPPATH);
    }







    /**
     * Add Package Path
     *
     * Extends package path to allow the form
     * paths
     *
     * @param string $path
     */
    public function  add_package_path($path) {
        $path = rtrim($path, '/').'/';

        array_unshift($this->_ci_form_paths, $path);

        parent::add_package_path($path);
    }







    /**
     * Database Loader
     *
     * @access    public
     * @param    string    the DB credentials
     * @param    bool    whether to return the DB object
     * @param    bool    whether to enable active record (this allows us to override the config setting)
     * @return    object
     */
    function database($params = '', $return = FALSE, $active_record = NULL)
    {
        // Grab the super object
        $CI =& get_instance();

        // Do we even need to load the database class?
        if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)) {
            return FALSE;
        }

        require_once(APPPATH.'database/DB'.EXT);

        // Load the DB class
        $db =& DB($params, $active_record);

        if($return !== false) {
            if(is_string($return)) {
                if(!isset($CI->db)) {
                    $CI->db = array(
                        $return => $db,
                    );
                } else {
                    $CI->db[$return] = $db;
                }
            }
            return $db;
        }

        // Initialize the db variable.  Needed to prevent
        // reference errors with some configurations
        $CI->db = '';
        $CI->db = $db;
    }
    
    
    
    
    
    
    
    /**
     * Load the Database Forge Class
     *
     * @return	string
     */
    public function dbforge() {
        if(!class_exists('CI_DB')) { $this->database(); }

        $objCI =& get_instance();
        
        require_once(BASEPATH.'database/DB_forge.php');
        
        if(isset($objCI->db)) {
            if(is_array($objCI->db)) {
                if(count($objCI->db) > 0) {
                    foreach($objCI->db as $id => $db) {
                        require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php');
                        
                        $my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_forge';
                        $my_driver_file = APPPATH.'database/'.$db->dbdriver.'/'.$my_driver.EXT;
                        
                        if(file_exists($my_driver_file)) {
                            require_once($my_driver_file);
                            $class = $my_driver;
                        } else {
                            $class = 'CI_DB_'.$db->dbdriver.'_forge';
                        }
                        
                        $objDBForge = new $class($id);
                        
                        $arrDBForge[$id] = $objDBForge;
                    }
                    
                    $CI->dbforge = $arrDBForge;
                }
            } else {
                require_once(BASEPATH.'database/drivers/'.$objCI->db->dbdriver.'/'.$objCI->db->dbdriver.'_forge.php');
        
                $class = 'CI_DB_'.$objCI->db->dbdriver.'_forge';
                
                $CI->dbforge = new $class;
            }
        } else {
            show_error('database is not in CI instance');
        }
    }
    
    
    
    
    
    
    
    /**
     * Load the Utilities Class
     *
     * @return	string
     */
    public function dbutil() {
        if(!class_exists('CI_DB')) { $this->database(); }

        $objCI =& get_instance();

        // for backwards compatibility, load dbforge so we can extend dbutils off it
        // this use is deprecated and strongly discouraged
        $objCI->load->dbforge();
        
        require_once(BASEPATH.'database/DB_utility.php');
        
        if(isset($objCI->db)) {
            if(is_array($objCI->db)) {
                if(count($objCI->db) > 0) {
                    foreach($objCI->db as $id => $db) {
                        require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php');
                        
                        $my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_utility';
                        $my_driver_file = APPPATH.'database/'.$db->dbdriver.'/'.$my_driver.EXT;
                        
                        if(file_exists($my_driver_file)) {
                            require_once($my_driver_file);
                            $class = $my_driver;
                        } else {
                            $class = 'CI_DB_'.$db->dbdriver.'_utility';
                        }
                        
                        $arrDBUtil[$id] = new $class($id);
                    }
                    
                    $objCI->dbutil = $arrDBUtil;
                }
            } else {
                require_once(BASEPATH.'database/drivers/'.$objCI->db->dbdriver.'/'.$objCI->db->dbdriver.'_utility.php');
                $class = 'CI_DB_'.$objCI->db->dbdriver.'_utility';

                $objCI->dbutil = new $class();
            }
        } else {
            show_error('database is not in CI instance');
        }
    }







    /**
     * Form
     *
     * Loads the form object
     * 
     * @param string $form
     * @param string $name
     * @return null
     */
    public function form($form, $name = '') {

        /* Load the form validation class */
        $objCI = &get_instance();
        $objCI->load->library('form_validation');

        if (is_array($form)) {
            foreach ($form as $babe) {
                $this->form($babe);
            }
            return;
        }

        if ($form == '') {
            return;
        }

        $path = '';

        // Is the form in a sub-folder? If so, parse out the filename and path.
        if (($last_slash = strrpos($form, '/')) !== FALSE) {
            // The path is in front of the last slash
            $path = substr($form, 0, $last_slash + 1);

            // And the form name behind it
            $form = substr($form, $last_slash + 1);
        }

        if ($name == '') {
            $name = $form;
        }

        if (in_array($name, $this->_ci_forms, TRUE)) {
            return;
        }

        $name = $form.'_form';
        $class = ucfirst($name);

        $CI =& get_instance();
        if (isset($CI->$class)) {
            show_error('The form name you are loading is the name of a resource that is already being used: '.$name);
        }

        foreach ($this->_ci_form_paths as $form_path) {

            if ( ! file_exists($form_path.'forms/'.$path.$form.EXT)) {
                continue;
            }

            if ( ! class_exists('MY_Form')) {
                load_class('Form', 'core');
            }
            
            require_once($form_path.'forms/'.$path.$form.EXT);

            $CI->$name = new $class();

            /* Run the autoload */
            if(method_exists($CI->$name, '__load')) { $CI->$name->__load(); }

            $this->_ci_forms[] = $class;

            return;

        }

        // couldn't find the form
        show_error('Unable to locate the form you have specified: '.$form);

    }
    
    
    
    
    
    
    
    public function ui($type, $location) {
        /* Lowercase the type */
        $type = strtolower($type);
        
        if(in_array($type, $this->_ui_types)) {
            
            /* Load the UI library */
            $objCI = &get_instance();
            $objCI->load->library('user_interface');
            
            /* Add the file */
            $objCI->user_interface->{$type}($location);
            
        } else {
            show_error("{$type} not a valid UI type");
        }
    }
    
    
    
    
}

?>